<?php
class TemplateException extends Exception {}

class Template
{
    public static $js_files=array(),
                  $js_keys=array();

    public static function get($name, $path = false, $cache = null)
    {
        if (! $path) {
            $source = getcwd()."/app/view/{$name}.phtml";
		    $destination = getcwd()."/tmp/cache/{$name}.php";
            
            if(! file_exists($source)) {
                return false;
            }
        } else {
            $source = getcwd()."/app/view/{$path}/{$name}.phtml";
		    $destination = getcwd()."/tmp/cache/{$path}/{$name}.php";
        }

        $s_time = filemtime($source);
		$d_time = file_exists($destination) ? filemtime($destination) : 0;

        if ($s_time > $d_time) {
		    $tpl_dir = dirname($destination);
		    if (! is_dir($tpl_dir)) {
				mkdir($tpl_dir, 0777, true);
		    }

		    $tpl = file_get_contents($source);

            if ($tpl === false) {
				throw new TplException("TPL: can't read file '{$source}'");
		    }

		    //$tpl = str_replace('{{LANG}}','_lang/'.language::localize($user), $tpl);

            $pattern = array(
                '/<%=?\s?\$([a-zA-Z_]+.*)\s?%>/U',
                /*'/<%~\s?\$([a-zA-Z_]+.*)\s?%>/U'*/
            );
            $replace = array(
                '<?php echo \$$1; ?>',
                /*'<?php echo escape(\$$1); ?>'*/
            );
            $tpl = preg_replace($pattern, $replace, $tpl);

//		    $tpl = preg_replace_callback('#\[\[(.*)\]\]#U','tpl::tpl_replace_callback', $tpl);
//
//            $pattern_cb = array(
//                '/{js=(.+)}/U',
//                '/{jst=(.+)}/U',
//            );
//		    $tpl = preg_replace_callback($pattern_cb,'tpl::jsf_replace_callback', $tpl);
		    //// end replace funcs

		    if (file_put_contents($destination, $tpl) === false) {
				throw new TemplateException("TPL: can't write file '{$destination}'");
		    }
		}
		return $destination;
    }

    public static function js_replace_callback($m)
    {
		$name = $m[1];
		$key = 'dynamic';

		self::$js_files[$key] .= "\n".$m[1]."\n";
		return '';
   	}

    public static function jsf_replace_callback($m)
    {
		global $_CONF;
		foreach($_CONF['js_cat'] as $k => $v)
		    if (in_array($m[1], $v)) {
			    self::$js_keys[$k] = 1;
			    return '';
		    }
		self::$js_files['current'][] = $m[1];
		return '';
    }

    public static function jst_replace_callback($m)
    {
		global $_CONF;
		self::$js_keys[$m[1]] = 1;
		return '';
    }
	/**
	* Callback used in regexp in function tpl() to escape single quotes and produce gettext call.
	*/
	public static function tpl_replace_callback($m)
	{
		return "<?php echo _('".str_replace("'", "\\'", $m[1])."');?>";
	}

    public static function inc($type, $module)
    {
		$mod = 'default';
		foreach (App::$config['alt_tpl'] as $k => $v) {
		    if (in_array($module, $v)) {
			    $mod = $k;
			    break;
		    }
		}
		if (! file_exists("view/elem/{$mod}/{$type}.phtml"))
		    return "default/{$type}";
		else
		    return "{$mod}/{$type}";
    }

    public static function truncate_string($str='')
    {
		global $_CONF;

        if (empty($str) || mb_strlen($str) <= $_CONF['MAX_LINE']) return $str;
			return mb_strcut($str, 0, ($_CONF['MAX_LINE'] / 2)).'...'.mb_strcut($str, -($_CONF['MAX_LINE'] / 2));
    }

    public static function escape($str='')
    {
		return htmlspecialchars($str, ENT_QUOTES);
    }

    protected static function _js_minify($js_name)
    {
		system("/root/jre1.6.0_14/bin/java -jar ../lib/vendor/yuicompressor.jar --type js --charset utf8 www/gen/{$js_name} -o www/gen/{$js_name}");
    }

    protected static function _js_gzip($js_name)
    {
		system("gzip -c9 www/gen/{$js_name} > www/gen/{$js_name}.gz");
    }

    protected static function _js_comress($js_name)
    {
		//self::js_minify($js_name);
		self::_js_gzip($js_name);
    }

    protected static function _mm_mtime($js_name,$time=0)
    {
		global $cache;
		if (! $time)
		    return intval($cache->get("tpl_mtime_{$js_name}"));
		else $cache->set("tpl_mtime_{$js_name}",$time);
    }

    protected static function _mm_listhash($ar,$crc=0)
    {
		global $cache;
        if (! sizeof($ar))
            return;

		$key = 'tpl_key_'.crc32(implode('?', $ar));
		if (! $crc)
		    return intval($cache->get($key));
		else
			$cache->set($key,$crc);
    }

    protected static function _js_trycachce($fkey,$flist)
    {
		$v='';
		$correct=1;
		if (sizeof($flist))
			foreach($flist as $vv) {
			    $mtime=filemtime("www/js/{$vv}.js");
			    if(self::_mm_mtime($vv) < $mtime) {
					$correct=0;
					self::_mm_mtime($vv, $mtime);
			    }
			}
		if ($correct) {
		    $crc=self::_mm_listhash($flist);
		    if (! $crc)
				$correct=0;
		}

		$crc=dechex($crc);
		$js_name = "{$fkey}_{$crc}.js";

		if (intval(@filesize("www/gen/{$js_name}") . '') < 2){
			$correct=0;
		}

		if (! $correct) {
			if (sizeof($flist))
			    foreach ($flist as $vv) {
					if (file_exists("www/js/{$vv}.js"))
					    $v.=file_get_contents("www/js/{$vv}.js");
					else {
					    die("/js/{$vv}.js not found!");
					}
			    }
		    $crc=crc32($v);
		    self::_mm_listhash($flist,$crc);
		}

		if (!file_exists("www/gen/{$js_name}") || intval(filesize("www/gen/{$js_name}").'') < 2) {
		    file_put_contents("www/gen/{$js_name}", $v);
		    self::_js_comress($js_name);
		}
		return $js_name;
    }

    public static function js_filter($str, $debug = 0)
    {
		global $_CONF;

		asort(self::$js_files);
		asort(self::$js_keys);
		/*
		 * Firstly process static sets of js
		 */
		if($debug) {
			$to_insert=array();
			foreach (self::$js_keys as $k => $v) {
				foreach ($_CONF['js_cat'][$k] as $vv)
					$to_insert[]=$vv;
			}
			foreach (self::$js_files as $k=>$v)
				$to_insert=array_merge($to_insert,$v);
			$js_str="";
			foreach ($to_insert as $v)
				$js_str.="<script src=\"/js/{$v}.js\" type=\"text/javascript\"></script>\n";
			if($js_str != '') {
			    $str=str_replace("</head>","{$js_str}</head>",$str);
			}
			$str = preg_replace('/{js}([\d\D]*){\/js}/U','<script  type="text/javascript">\\1</script>', $str);
			return $str;
		}

		$js_str='';
		foreach (self::$js_keys as $k => $p) {

		    $js_name = self::_js_trycachce($k,$_CONF['js_cat'][$k]);
		    $js_str .= "<script src=\"/gen/{$js_name}\" type=\"text/javascript\"></script>";
		}
		$str = str_replace('</body>',"{$js_str}\n</body>",$str);

		/*
		 * After process of static sets let's start process set for current page
		 */
		$js_name=self::_js_trycachce("current",self::$js_files['current']);
		//echo $js_name;
		$js_str="<script src=\"/gen/{$js_name}\" type=\"text/javascript\"></script>";

		$str=str_replace('</body>',"{$js_str}\n</body>",$str);

		/*
		 * Process JS into html.
		 * May be not needed!
		 * inline JS will NOT work if it uses any libs in foreing files.
		 */
		$str = preg_replace_callback('/{js}([\d\D]*){\/js}/U','tpl::js_replace_callback', $str);
		$k='dynamic';
		$v=self::$js_files[$k];
		$v=trim($v);
		if($v!='') {
		    $str=str_replace('</body>',"<script  type=\"text/javascript\">{$v}</script>\n</body>",$str);
		}
		return $str;
    }
}